#ifndef __ISR_H__
#define __ISR_H__

#include <types.h>

#define ISR_LENGTH			IDT_LENGTH

#define ISR_OK				0x0
#define ISR_BAD_INDEX		0x1
#define ISR_INDEX_IN_USE	0x2

typedef struct str_task_state
{
	// Registros cargados por "pusha"
	
	uint_32 edi;
	uint_32 esi;
	uint_32 ebp;
	uint_32 esp;
	uint_32 ebx;
	uint_32 edx;
	uint_32 ecx;
	uint_32 eax;

	// Registros de segmentos
	
	uint_16 gs;
	uint_16 :16;
	uint_16 fs;
	uint_16 :16;
	uint_16 es;
	uint_16 :16;
	uint_16 ds;
	uint_16 :16;
	uint_16 ss;
	uint_16 :16;

	// Estado cargado al producirse la interrupcion

	uint_32 eip;
	uint_16 cs;
	uint_16 :16;
	uint_32 eflags;

	// Estado adicional que se carga si hubo cambio de nivel al producirse la interrupcion

	uint_32 org_esp;
	uint_16 org_ss;
	uint_16 :16;

} task_state;

/* Números de interrupciones */

#define ISR_DIVIDE     	 0		// Divide Error
#define ISR_DEBUG      	 1		// debug exception
#define ISR_NMI        	 2		// non-maskable interrupt
#define ISR_BRKPT      	 3		// breakpoint
#define ISR_OFLOW      	 4		// overflow
#define ISR_BOUND      	 5		// bounds check
#define ISR_ILLOP        6		// illegal opcode
#define ISR_DEVICE     	 7		// device not available 
#define ISR_DBLFLT     	 8		// double fault
#define ISR_COPRO      	 9		// coprocesor (WTF!!)
#define ISR_TSS       	10		// invalid task switch segment
#define ISR_SEGNP     	11		// segment not present
#define ISR_STACK     	12		// stack exception
#define ISR_GPFLT		13		// genernal protection fault
#define ISR_PGFLT		14		// page fault
#define ISR_RES    		15		// reserved
#define ISR_FPERR		16		// floating point error
#define ISR_ALIGN		17		// aligment check
#define ISR_MCHK		18		// machine check
#define ISR_SIMDERR		19		// SIMD floating point error

/* Número de interrupciones para las PIC */

#define ISR_IRQ0    0x20		// Timer tick
#define ISR_IRQ1    0x21		// Teclado
#define ISR_IRQ2    0x22		// Cascada de la IRQ9
#define ISR_IRQ3    0x23		// Default COM2 y COM4
#define ISR_IRQ4    0x24		// Default COM1 y COM3
#define ISR_IRQ5    0x25		// LPT2
#define ISR_IRQ6    0x26		// Floppy Drive Controller
#define ISR_IRQ7    0x27		// LPT1

#define ISR_IRQ8    0x28		// Real Time Clock
#define ISR_IRQ9    0x29		// 
#define ISR_IRQ10   0x2A		// Reserved
#define ISR_IRQ11   0x2B		// Reserved
#define ISR_IRQ12   0x2C		// PS/2 mouse
#define ISR_IRQ13   0x2D		// Math coprocessor
#define ISR_IRQ14   0x2E		// Primary IDE
#define ISR_IRQ15   0x2F		// Secondary IDE

typedef void (*isr_ptr)(uint_32 index, uint_32 error_code, task_state *st);

void isr_init();
uint_32 isr_register(uint_32 index, isr_ptr isr);

#endif /* __ISR_H__ */
